package com.ruoyi.collect.utils;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.movie.domain.MovieBasics;
import org.springframework.stereotype.Component;

import java.util.regex.Pattern;

/**
 * 数据去重工具类
 *
 * @author ruoyi
 * @date 2025-11-07
 */
@Component
public class DataDeduplicator {

    // 标题相似度阈值
    private static final double SIMILARITY_THRESHOLD = 0.85;

    // 标题清理正则
    private static final Pattern CLEAN_PATTERN = Pattern.compile("[\\s\\-_\\[\\]【】()（）]");

    /**
     * 判断两部影视是否重复
     *
     * @param movie1 影视1
     * @param movie2 影视2
     * @return 是否重复
     */
    public boolean isDuplicate(MovieBasics movie1, MovieBasics movie2) {
        if (movie1 == null || movie2 == null) {
            return false;
        }

        // 1. 如果采集来源和采集ID相同，认为是同一部
        if (StringUtils.isNotEmpty(movie1.getCollectFrom()) &&
            movie1.getCollectFrom().equals(movie2.getCollectFrom()) &&
            StringUtils.isNotEmpty(movie1.getCollectId()) &&
            movie1.getCollectId().equals(movie2.getCollectId())) {
            return true;
        }

        // 2. 标题完全相同 + 年份相同
        if (StringUtils.isNotEmpty(movie1.getTitle()) &&
            movie1.getTitle().equals(movie2.getTitle()) &&
            movie1.getYear() != null &&
            movie1.getYear().equals(movie2.getYear())) {
            return true;
        }

        // 3. 清理后的标题相似 + 年份相同
        String cleanTitle1 = cleanTitle(movie1.getTitle());
        String cleanTitle2 = cleanTitle(movie2.getTitle());
        if (StringUtils.isNotEmpty(cleanTitle1) &&
            StringUtils.isNotEmpty(cleanTitle2) &&
            movie1.getYear() != null &&
            movie1.getYear().equals(movie2.getYear())) {

            double similarity = calculateSimilarity(cleanTitle1, cleanTitle2);
            if (similarity >= SIMILARITY_THRESHOLD) {
                return true;
            }
        }

        // 4. 英文标题相同 + 年份相同
        if (StringUtils.isNotEmpty(movie1.getTitleEn()) &&
            StringUtils.isNotEmpty(movie2.getTitleEn()) &&
            movie1.getTitleEn().equalsIgnoreCase(movie2.getTitleEn()) &&
            movie1.getYear() != null &&
            movie1.getYear().equals(movie2.getYear())) {
            return true;
        }

        return false;
    }

    /**
     * 清理标题
     * 去除空格、标点符号等
     *
     * @param title 原始标题
     * @return 清理后的标题
     */
    public String cleanTitle(String title) {
        if (StringUtils.isEmpty(title)) {
            return "";
        }

        // 转小写
        String cleaned = title.toLowerCase();

        // 去除特殊字符
        cleaned = CLEAN_PATTERN.matcher(cleaned).replaceAll("");

        // 去除常见后缀
        cleaned = removeCommonSuffixes(cleaned);

        return cleaned.trim();
    }

    /**
     * 去除常见后缀
     *
     * @param title 标题
     * @return 处理后的标题
     */
    private String removeCommonSuffixes(String title) {
        String[] suffixes = {
            "hd", "bd", "dvd", "tc", "ts", "cam", "r5", "r6",
            "中文字幕", "中字", "国语", "粤语", "英语",
            "1080p", "720p", "480p", "4k", "蓝光",
            "正片", "完整版", "未删减版", "导演剪辑版"
        };

        String result = title;
        for (String suffix : suffixes) {
            result = result.replace(suffix, "");
        }
        return result;
    }

    /**
     * 计算两个字符串的相似度（Levenshtein距离）
     *
     * @param s1 字符串1
     * @param s2 字符串2
     * @return 相似度（0-1之间）
     */
    public double calculateSimilarity(String s1, String s2) {
        if (StringUtils.isEmpty(s1) && StringUtils.isEmpty(s2)) {
            return 1.0;
        }
        if (StringUtils.isEmpty(s1) || StringUtils.isEmpty(s2)) {
            return 0.0;
        }

        int distance = levenshteinDistance(s1, s2);
        int maxLength = Math.max(s1.length(), s2.length());
        return 1.0 - (double) distance / maxLength;
    }

    /**
     * 计算Levenshtein距离
     *
     * @param s1 字符串1
     * @param s2 字符串2
     * @return 编辑距离
     */
    private int levenshteinDistance(String s1, String s2) {
        int len1 = s1.length();
        int len2 = s2.length();

        int[][] dp = new int[len1 + 1][len2 + 1];

        for (int i = 0; i <= len1; i++) {
            dp[i][0] = i;
        }
        for (int j = 0; j <= len2; j++) {
            dp[0][j] = j;
        }

        for (int i = 1; i <= len1; i++) {
            for (int j = 1; j <= len2; j++) {
                int cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1;
                dp[i][j] = Math.min(
                    Math.min(dp[i - 1][j] + 1, dp[i][j - 1] + 1),
                    dp[i - 1][j - 1] + cost
                );
            }
        }

        return dp[len1][len2];
    }

    /**
     * 生成影视指纹
     * 用于快速去重判断
     *
     * @param movie 影视信息
     * @return 指纹字符串
     */
    public String generateFingerprint(MovieBasics movie) {
        if (movie == null) {
            return "";
        }

        StringBuilder fingerprint = new StringBuilder();

        // 标题
        if (StringUtils.isNotEmpty(movie.getTitle())) {
            fingerprint.append(cleanTitle(movie.getTitle()));
        }

        // 年份
        if (movie.getYear() != null) {
            fingerprint.append("_").append(movie.getYear());
        }

        // 导演文本
        if (StringUtils.isNotEmpty(movie.getDirectorText())) {
            String[] directors = movie.getDirectorText().split("[,，/]");
            if (directors.length > 0) {
                fingerprint.append("_").append(directors[0].trim());
            }
        }

        return fingerprint.toString().toLowerCase();
    }

    /**
     * 判断是否为有效的影视数据
     *
     * @param movie 影视信息
     * @return 是否有效
     */
    public boolean isValidMovie(MovieBasics movie) {
        if (movie == null) {
            return false;
        }

        // 必须有标题
        if (StringUtils.isEmpty(movie.getTitle())) {
            return false;
        }

        // 标题长度检查
        if (movie.getTitle().length() < 2 || movie.getTitle().length() > 200) {
            return false;
        }

        // 过滤测试数据
        String lowerTitle = movie.getTitle().toLowerCase();
        if (lowerTitle.contains("test") ||
            lowerTitle.contains("测试") ||
            lowerTitle.contains("示例")) {
            return false;
        }

        return true;
    }

    /**
     * 计算数据质量分数
     * 根据完整度评分，用于选择保留哪条数据
     *
     * @param movie 影视信息
     * @return 质量分数（0-100）
     */
    public int calculateQualityScore(MovieBasics movie) {
        if (movie == null) {
            return 0;
        }

        int score = 0;

        // 基础信息（40分）
        if (StringUtils.isNotEmpty(movie.getTitle())) score += 10;
        if (StringUtils.isNotEmpty(movie.getPoster())) score += 10;
        if (movie.getYear() != null) score += 10;
        if (StringUtils.isNotEmpty(movie.getSummary())) score += 10;

        // 详细信息（30分）
        if (StringUtils.isNotEmpty(movie.getDirectorText())) score += 10;
        if (StringUtils.isNotEmpty(movie.getActorText())) score += 10;
        if (StringUtils.isNotEmpty(movie.getArea())) score += 5;
      //  if (StringUtils.isNotEmpty(movie.getLanguage())) score += 5;

        // 评分信息（15分）
       // if (movie.getRating() != null && movie.getRating() > 0) score += 15;

        // 描述完整度（15分）
        /*if (StringUtils.isNotEmpty(movie.getDescription())) {
            int descLength = movie.getDescription().length();
            if (descLength > 500) score += 15;
            else if (descLength > 200) score += 10;
            else if (descLength > 50) score += 5;
        }*/

        return Math.min(score, 100);
    }
}